#include "io_config.h"
#if API_ENABLE_CONFIG_IO
#include "http_server.h"
#include "api_map.h"

typedef struct io_config_list
{
    struct io_config_list *next;
    io_config_fn_t fn;
} io_config_list_s, *io_config_list_t;
static io_config_list_t list_head = NULL;
static io_config_list_t list_end = NULL;

void io_config_add(io_config_fn_t fn)
{
    io_config_list_t item = malloc(sizeof(io_config_list_s));
    item->fn = fn;
    item->next = NULL;
    if (!list_head)
        list_head = item;
    if (list_end)
        list_end->next = item;
    list_end = item;
}

void io_config_remove(io_config_fn_t fn)
{
    io_config_list_t last = NULL;
    for (io_config_list_t item = list_head; item; item = item->next)
    {
        if (item->fn == fn)
        {
            if (!last)
                list_head = item->next;
            else
                last->next = item->next;
            if (list_end == item)
                list_end = last;
            free(item);
            break;
        }
        last = item;
    }
}

uint16_t io_config_call(http_server_t server, httpd_ws_frame_t *frame, void *data)
{
    if (!list_head)
        return 0;
    uint16_t len = 0;
    for (io_config_list_t item = list_head; item; item = item->next)
        len += item->fn(server, frame, data);
    return len;
}

static void get_config_io(http_server_t server, httpd_ws_frame_t *frame, void *data)
{
    uint16_t len = 0;
    char *str = (char *)server->data;
    len += sprintf(&str[len], "{");
    len += sprintf(&str[len], "\"api\":\"get_config_io\",");
    len += sprintf(&str[len], "\"data\":{");
    len += io_config_call(server, frame, 0);
    len -= 1;
    len += sprintf(&str[len], "}");
    len += sprintf(&str[len], "}");
    frame->payload = server->data;
    frame->len = len;
}

static void set_config_io(http_server_t server, httpd_ws_frame_t *frame, void *data)
{
    uint16_t len = 0;
    char *str = (char *)server->data;
    len += sprintf(&str[len], "{");
    len += sprintf(&str[len], "\"api\":\"set_config_io\",");
    len += sprintf(&str[len], "\"data\":{");
    len += io_config_call(server, frame, data);
    len -= 1;
    len += sprintf(&str[len], "}");
    len += sprintf(&str[len], "}");
    frame->payload = server->data;
    frame->len = len;
}

static void io_config_init(void)
{
    ADD_API_ITEM(get_config_io);
    ADD_API_ITEM(set_config_io);
}
ADD_API(io_config_init)
#endif
